CloudWatch Alarmのステート変更時にEventBridge経由でStep Functionsステートマシンを起動してみた(AWS CDK v2)
こんにちは、CX事業本部 IoT事業部の若槻です。
AWSで新しい機能が追加されたり、また自分が見つけたりして、同じことを実現するシステムを以前よりシンプル(マネージド)な構成で実現できた時って小躍りしたくなりますよね。
今回は、CloudWatch Alarmのステート変更時にEventBridge経由でStep Functionsステートマシンを起動する構成をAWS CDK v2で作ってみました。
EventBridgeを使うことにより、同じシステムを以前紹介した時の構成よりもシンプルにすることができました。
やってみた
下記のような構成を作成してみます。
CDKコード
AWS CDKのStack定義のコードです。
import { Construct } from 'constructs'; import { aws_cloudwatch, aws_events, aws_events_targets, aws_stepfunctions, Duration, Stack, StackProps, } from 'aws-cdk-lib'; export class ProcessStack extends Stack { constructor(scope: Construct, id: string, props: StackProps) { super(scope, id, props); //Step Functions State Machine const testStateMachine = new aws_stepfunctions.StateMachine( this, 'testStateMachine', { stateMachineName: 'testStateMachine', definition: new aws_stepfunctions.Choice(this, 'whetherAlarmOrNot') .when( aws_stepfunctions.Condition.stringEquals( '$.detail.state.value', 'ALARM' ), new aws_stepfunctions.Pass(this, 'Alarm occurs!') ) .otherwise(new aws_stepfunctions.Pass(this, 'No Alarm.')), } ); //CloudWatch Alarm const testAlarm = new aws_cloudwatch.Alarm(this, 'testAlarm', { alarmName: 'testAlarm', metric: new aws_cloudwatch.Metric({ namespace: 'participants', metricName: 'area_01', dimensionsMap: { Site: 'A' }, statistic: aws_cloudwatch.Statistic.MAXIMUM, period: Duration.minutes(1), }), evaluationPeriods: 10, threshold: 5, comparisonOperator: aws_cloudwatch.ComparisonOperator.LESS_THAN_OR_EQUAL_TO_THRESHOLD, treatMissingData: aws_cloudwatch.TreatMissingData.MISSING, }); //EventBridge Rule new aws_events.Rule(this, 'testAlarmRule', { ruleName: 'testAlarmRule', eventPattern: { source: ['aws.cloudwatch'], detailType: ['CloudWatch Alarm State Change'], resources: [testAlarm.alarmArn], }, targets: [new aws_events_targets.SfnStateMachine(testStateMachine)], }); } }
- ステートマシンは、起動トリガーとなったAlarmの変更先ステートが
ALARM
がそうでないかで分岐するワークフローとしています。 - EventBridge Ruleのイベントパターンは、CloudWatch Alarmイベントを使用したい場合はアラームのページから指定するべきパターンが確認できます。
CDK Deployしてリソースをデプロイします。
動作確認
アラームのステートをALARM
に手動変更します。
$ aws cloudwatch set-alarm-state \ --alarm-name testAlarm \ --state-value ALARM \ --state-reason "test"
CloudWatch AlarmのステートがINSUFFICIENT_DATA
からALARM
に変更されました。
ステートマシンの実行詳細を見ると、Graph viewはアラーム発生時の分岐となっています。
実行のInputは次のようになります。detail
では今回(state
)と前回(previousState
)のステートやメトリクスの情報が含まれています。これらの情報を元にステートマシン内で柔軟な処理を行えそうですね。
{ "version": "0", "id": "148399e2-88ac-c35a-3648-d2cc2e8b06b1", "detail-type": "CloudWatch Alarm State Change", "source": "aws.cloudwatch", "account": "XXXXXXXXXXXX", "time": "2022-05-24T14:25:01Z", "region": "ap-northeast-1", "resources": [ "arn:aws:cloudwatch:ap-northeast-1:XXXXXXXXXXXX:alarm:testAlarm" ], "detail": { "alarmName": "testAlarm", "state": { "value": "ALARM", "reason": "test", "timestamp": "2022-05-24T14:25:01.829+0000" }, "previousState": { "value": "INSUFFICIENT_DATA", "reason": "Insufficient Data: 10 datapoints were unknown.", "reasonData": "{\"version\":\"1.0\",\"queryDate\":\"2022-05-24T14:13:19.816+0000\",\"statistic\":\"Maximum\",\"period\":60,\"recentDatapoints\":[],\"threshold\":5.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2022-05-24T14:12:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:11:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:10:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:09:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:08:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:07:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:06:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:05:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:04:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:03:00.000+0000\"}]}", "timestamp": "2022-05-24T14:13:19.820+0000" }, "configuration": { "metrics": [ { "id": "96c07b31-ffe0-59ae-6609-f8e608d124f7", "metricStat": { "metric": { "namespace": "participants", "name": "area_01", "dimensions": { "Site": "A" } }, "period": 60, "stat": "Maximum" }, "returnData": true } ] } } }
また、ステートがALARM
からINSUFFICIENT_DATA
へ戻った際にもEventBridge Ruleは発行されます。
それにより起動された実行の詳細は次のようになります。Graph viewはアラームでない時の分岐となっています。
実行のInputでは先程と同様な情報を取得できます。
{ "version": "0", "id": "20f3f515-0f1d-e497-4f94-11a6d77a98e0", "detail-type": "CloudWatch Alarm State Change", "source": "aws.cloudwatch", "account": "XXXXXXXXXXXX", "time": "2022-05-24T14:25:19Z", "region": "ap-northeast-1", "resources": [ "arn:aws:cloudwatch:ap-northeast-1:XXXXXXXXXXXXs:alarm:testAlarm" ], "detail": { "alarmName": "testAlarm", "state": { "value": "INSUFFICIENT_DATA", "reason": "Insufficient Data: 10 datapoints were unknown.", "reasonData": "{\"version\":\"1.0\",\"queryDate\":\"2022-05-24T14:25:19.816+0000\",\"statistic\":\"Maximum\",\"period\":60,\"recentDatapoints\":[],\"threshold\":5.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2022-05-24T14:24:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:23:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:22:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:21:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:20:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:19:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:18:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:17:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:16:00.000+0000\"},{\"timestamp\":\"2022-05-24T14:15:00.000+0000\"}]}", "timestamp": "2022-05-24T14:25:19.821+0000" }, "previousState": { "value": "ALARM", "reason": "test", "timestamp": "2022-05-24T14:25:01.829+0000" }, "configuration": { "metrics": [ { "id": "96c07b31-ffe0-59ae-6609-f8e608d124f7", "metricStat": { "metric": { "namespace": "participants", "name": "area_01", "dimensions": { "Site": "A" } }, "period": 60, "stat": "Maximum" }, "returnData": true } ] } } }
おわりに
CloudWatch Alarmのステート変更時にEventBridge経由でStep Functionsステートマシンを起動する構成をAWS CDK v2で作ってみました。
EventBridgeのことを分かっているつもりでまだまだ全然活用できていませんでした。同じことをするのにLambda関数が1つ不要になるってすごく嬉しいですね。
参考
- CloudWatch Alarmでアラーム発生時にStep Functionsステートマシンを起動する | DevelopersIO
- [Amazon CloudWatch] カスタムメトリクスにアラームを設定してみた(AWS CDK) | DevelopersIO
- Amazon EventBridgeのデフォルトバスの動作をイベントパターンで確認してみた | DevelopersIO
- CloudWatch AlarmですでにALARM状態のアラームでアラームを手動発生させる | DevelopersIO
以上